#include "EngineLoop.h"
#include "Engine.h"
#include "GameEngine.h"
#include "Runtime/CGI/DynamicCGI.h"
#include "Runtime/Engine/Application.h"
#include "Runtime/Engine/2D/SlaveRenderer.h"
#include "Runtime/Rendering/Core/RenderCommandFence.h"
#include "Runtime/Rendering/Core/RenderingThread.h"
#include "Runtime/Thread/RenderingThreadContext.h"
#include "Runtime/Thread/ThreadPool.h"
static Alice::EngineLoop*sEngineLoop=nullptr;
namespace Alice{
    //game
    //render
    //rhi
    static RenderCommandFence sRenderCommandFences[3];
    int32 EngineLoop::Init(){
        mCurrentFrameIndex=2;
        ThreadPoolInterface::Get().Startup(PlatformMisc::NumberOfWorkerThreadsToSpawn());
        Application::Create();
        CGIInit();
        Application::Get()->InitializeRenderer(new SlaveCGIRenderer);
        InitRenderingThread();
        gEngine=new GameEngine;
        gEngine->Init(this);
        return 0;
    }
    void EngineLoop::Tick(){
        gEngine->Tick(0.0f);
        Application::Get()->Tick();
        Sync();
    }
    void EngineLoop::Sync(bool bFullSync)
    {
        uint32 lastFrameIndex=mCurrentFrameIndex;
        mCurrentFrameIndex=(mCurrentFrameIndex+1)%3;
        sRenderCommandFences[0].BeginFence();
        ENQUEUE_RENDER_COMMAND(EndFrame)([lastFrameIndex](CGICommandList&inCGICommandList)
        {
            sRenderCommandFences[0].mEvent->TriggerAll();
        });
        sRenderCommandFences[0].mEvent->Wait();
    }
    void EngineLoop::ClearPendingCleanupObjects(){
        
    }
}
int32 EngineInit(){
    sEngineLoop=new Alice::EngineLoop;
    sEngineLoop->Init();
    return 0;
}
void EngineTick(){
    sEngineLoop->Tick();
}